<?php
/**
 * @file
 */

/**
 * Implements of hook_entity_info()
 */
function nodejschat_client_entity_info() {
  $return = array(
    'nodejschat_client' => array(
      'label' => t('NodejsChat Client'),
      'controller class' => 'NodejsChatClientController',
      'base table' => 'nodejschat_client',
      'uri callback' => 'nodejschat_client_uri',
      'fieldable' => TRUE,
      'entity keys' => array(
        'id' => 'ncid',
      ),
      'bundles' => array(
        'nodejschat_client' => array(
          'label' => t('NodejsChat Client'),
          'admin' => array(
            'path' => 'admin/config/nodejschat/client',
            'access arguments' => array('administer nodejschat'),
          ),
        ),
      ),
      'view modes' => array(
        'full' => array(
          'label' => t('NodejsChat Client'),
          'custom settings' => FALSE,
        ),
      ),
    ),
  );
  return $return;
}

/**
 * Implements hook_field_info_alter().
 */
function nodejschat_client_field_info_alter(&$info) {
  // Add the 'nodejschat_client_form' instance setting to all field types.
  foreach ($info as $field_type => &$field_type_info) {
    $field_type_info += array('instance_settings' => array());
    $field_type_info['instance_settings'] += array(
      'nodejschat_client_form' => FALSE,
    );
  }
}

/**
 * Implements hook_field_extra_fields().
 */
function nodejschat_client_field_extra_fields() {
  $return['nodejschat_client']['nodejschat_client'] = array(
    'form' => array(
      'name' => array(
        'label' => t('Full name'),
        'description' => t('nodejschat_client module name form elements.'),
        'weight' => -10,
      ),
      'email' => array(
        'label' => t('Email'),
        'description' => t('nodejschat_client module email form element.'),
        'weight' => 6,
      ),
    ),
    'display' => array(
      'summary' => array(
        'label' => t('Client'),
        'description' => t('nodejschat_client module client view element.'),
        'weight' => 5,
      ),
    ),
  );

  return $return;
}


/**
 * Implements callback_entity_info_uri().
 */
function nodejschat_client_uri($nodejschat_client) {
  return array(
    'path' => 'nodejschat-client/' . $nodejschat_client->ncid,
    'options' => array('fragment' => 'nodejschat-client-' . $nodejschat_client->cid),
  );
}

/**
 * Saves changes to a node or adds a new nodejschat client.
 *
 * @param $client
 *   The $client object to be saved. If $client->ncid is
 *   omitted (or $client->is_new is TRUE), a new nodejschat will be added.
 */
function nodejschat_client_save($client) {
  $transaction = db_transaction();

  try {
    field_attach_presave('nodejschat_client', $client);

    // Determine if we will be inserting a new node.
    if (!isset($client->is_new)) {
      $client->is_new = empty($client->ncid);
    }

    $client->modified = REQUEST_TIME;

    // Let modules modify the node before it is saved to the database.
    module_invoke_all('nodejschat_client_presave', $client);
    module_invoke_all('entity_presave', $client, 'nodejschat_client');

    // Save the node and node revision.
    if ($client->is_new) {
      // For new nodejschat, save new records for the nodejschat itself
      global $user;
      $client->uid = $user->uid;
      drupal_write_record('nodejschat_client', $client);
      $op = 'insert';
    }
    else {
      // For existing nodejschat, update the nodejschat record which matches the value of
      // $nodejschat->cid.
      drupal_write_record('nodejschat_client', $client, 'cid');
      $op = 'update';
    }

    // Save fields.
    $function = "field_attach_$op";
    $function('nodejschat_client', $client);

    module_invoke_all('nodejschat_client_' . $op, $client);
    module_invoke_all('entity_' . $op, $client, 'nodejschat');

    // Clear internal properties.
    unset($client->is_new);
    // Clear the static loading cache.
    entity_get_controller('nodejschat_client')->resetCache(array($client->ncid));

    // Ignore slave server temporarily to give time for the
    // saved nodejschat to be propagated to the slave.
    db_ignore_slave();
  }
  catch (Exception $e) {
    $transaction->rollback();
    watchdog_exception('nodejschat_client', $e);
    throw $e;
  }
}

/**
 * Deletes a nodejschat_client.
 *
 * @param $cid
 *   A nodejschat ID.
 */
function nodejschat_client_delete($ncid) {
  nodejschat_client_delete_multiple(array($ncid));
}

/**
 * Deletes multiple nodejschats.
 *
 * @param $cids
 *   An array of nodejschat IDs.
 */
function nodejschat_client_delete_multiple($ncids) {
  $transaction = db_transaction();
  if (!empty($ncids)) {
    $clients = nodejschat_load_multiple($ncids, array());

    try {
      foreach ($clients as $ncid => $client) {
        // Call the node-specific callback (if any):
        module_invoke_all('nodejschat_client_delete', $client);
        module_invoke_all('entity_delete', $client, 'nodejschat_client');
        field_attach_delete('nodejschat_client', $client);

        // Remove this node from the search index if needed.
        // This code is implemented in node module rather than in search module,
        // because node module is implementing search module's API, not the other
        // way around.
        if (module_exists('search')) {
          search_reindex($ncid, 'nodejschat_client');
        }
      }

      // Delete after calling hooks so that they can query node tables as needed.
      db_delete('nodejschat_client')
        ->condition('cid', $ncids, 'IN')
        ->execute();
    }
    catch (Exception $e) {
      $transaction->rollback();
      watchdog_exception('nodejschat_client', $e);
      throw $e;
    }

    // Clear the page and block and node_load_multiple caches.
    entity_get_controller('nodejschat_client')->resetCache();
  }
}

/**
 * Load the entire nodejschat by cid.
 *
 * @param $cid
 *   The identifying comment id.
 * @param $reset
 *   Whether to reset the internal static entity cache. Note that the static
 *   cache is disabled in comment_entity_info() by default.
 *
 * @return
 *   The comment object.
 */
function nodejschat_client_load($ncid, $reset = FALSE) {
  $client = nodejschat_client_load_multiple(array($ncid), array(), $reset);
  return $client ? $client[$ncid] : FALSE;
}

/**
 * Load nodejschats from the database.
 *
 * @param $cids
 *   An array of nodejschat IDs.
 * @param $conditions
 *   (deprecated) An associative array of conditions on the {nodejschats}
 *   table, where the keys are the database fields and the values are the
 *   values those fields must have. Instead, it is preferable to use
 *   EntityFieldQuery to retrieve a list of entity IDs loadable by
 *   this function.
 * @param $reset
 *   Whether to reset the internal static entity cache. Note that the static
 *   cache is disabled in nodejschat_entity_info() by default.
 *
 * @return
 *   An array of comment objects, indexed by nodejschat ID.
 *
 * @see entity_load()
 * @see EntityFieldQuery
 *
 * @todo Remove $conditions in Drupal 8.
 */
function nodejschat_client_load_multiple($ncids = array(), $conditions = array(), $reset = FALSE) {
  return entity_load('nodejschat_client', $ncids, $conditions, $reset);
}

/**
 * Get chat from session id
 */
function nodejschat_client_load_by_sid($sid = '') {
  if (empty($sid)) {
    $sid = session_id();
  }
  $clients = nodejschat_client_load_multiple(array(), array('sid' => $sid));
  return reset($clients);
  return FALSE;
}


/**
 * Controller class for users.
 *
 * This extends the DrupalDefaultEntityController class, adding required
 * special handling for user objects.
 */
class NodejsChatClientController extends DrupalDefaultEntityController {
  function attachLoad(&$clients, $revision_id = FALSE) {
    foreach ($clients as $key => $record) {
      $clients[$key]->nodejschat = FALSE;
      if ($nodejschat = nodejschat_load_by_sid($record->sid)) {
        $clients[$key]->nodejschat = $nodejschat;
      }
    }
    // Call the default attachLoad() method. This will add fields and call
    // hook_nodejschat_client_load().
    parent::attachLoad($clients, $revision_id);
  }
}